/*****************************************************
*                                                                          
*               COPYRIGHT (c) 2015-2017 Hargic Corporation              
*                         All Rights Reserved                              
*                                                                          
* The source code contained or described herein and all documents          
* related to the source code ("Material") are owned by Hargic         
* Corporation or its licensors.  Title to the Material remains             
* with Hargic Corporation or its suppliers and licensors.               
*                                                                          
* The Material is protected by worldwide copyright and trade secret        
* laws and treaty provisions. No part of the Material may be used,         
* copied, reproduced, modified, published, uploaded, posted, transmitted,  
* distributed, or disclosed in any way except in accordance with the       
* applicable license agreement.                                            
*                                                                          
* No license under any patent, copyright, trade secret or other            
* intellectual property right is granted to or conferred upon you by       
* disclosure or delivery of the Materials, either expressly, by            
* implication, inducement, estoppel, except in accordance with the         
* applicable license agreement.                                            
*                                                                          
* Unless otherwise agreed by Hargic in writing, you may not remove or   
* alter this notice or any other notice embedded in Materials by Hargic 
* or Hargic's suppliers or licensors in any way.                        
*                                                                          
** Author: ted.huang
** Date: 2018-02-25
*
*****************************************************/

/***** Include files ********************************/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

#include "cJSON.h"

#include "syslog.h"

/***** Defines **************************************/
#define MAX_CHILD_NUM_IN_GROUP          8

/***** Define structure *****************************/

typedef struct child_grp
{
    unsigned char   alive;
    pid_t           pid;
} child_grp_t;

/***** Define constant ******************************/

/***** Define global ********************************/
child_grp_t     child[MAX_CHILD_NUM_IN_GROUP];

/***** Define Prototype of functions ****************/

static void child_process(int cnt)
{
    unsigned char buff[16];
    int i;

    printf("%s: enter cnt %d\n", __func__, cnt);

    sleep(cnt);

    for (i=0; i<16; i++)
        buff[i] = i;

    syslog_save_info(buff, 16, cnt * 16);
    syslog_dump_mem("child dump", 0, 256);

    syslog_uninit();
}

static int add_new_child(pid_t pid)
{
    int i;

    for (i=0; i<MAX_CHILD_NUM_IN_GROUP; i++)
    {
        if (child[i].alive != 0)
            continue;

        child[i].pid = pid;
        child[i].alive = !0;
        printf("%s: add new child %d\n", __func__, pid);
        return i;
    }
    fprintf(stderr, "%s: add new child failed\n", __func__);
    return -1;
}

static int del_child(pid_t pid)
{
    int i;

    for (i=0; i<MAX_CHILD_NUM_IN_GROUP; i++)
    {
        if (child[i].alive == 0)
            continue;

        if (child[i].pid != pid)
            continue;

        child[i].alive = 0;
        printf("%s: del child %d\n", __func__, pid);
        return 0;
    }
    fprintf(stderr, "%s: pid %d not in child\n", __func__, pid);
    return -1;
}

static int is_child_empty(void)
{
    int i;

    for (i=0; i<MAX_CHILD_NUM_IN_GROUP; i++)
    {
        if (child[i].alive != 0)
            return 0;
    }
    return !0;
}

static void parent_process(void)
{
    int stat_val;
    pid_t child_pid;

    while (is_child_empty() == 0)
    {
        child_pid = wait(&stat_val);

        del_child(child_pid);

        printf("%s: child pid %d has complete\n", __func__, child_pid);
        // if (WIFEXITED(stat_val))
        //     printf("%s: child exited with code %d\n", __func__, WEXITSTATE(stat_val));
        // else
        //     printf("%s: child terminated abnormally\n", __func__);
    }

    syslog_shm_del();
}

/**
 * @brief
 * @param  None
 * @retval None
 */
int main(int argc, char **argv)
{
    pid_t pid;
    int i;

	syslog_shm_create();

    for (i=0; i<MAX_CHILD_NUM_IN_GROUP; i++)
    {
        pid = fork();
        if (pid == -1)
        {
            fprintf(stderr, "%s: fork failed\n", __func__);
            exit(-1);
        }
        else if (pid == 0)
        {
            break;
        }
        else
        {
            add_new_child(pid);
        }
    }
    if (pid == 0)
    {
        child_process(i);
    }
    else if (pid > 0)
    {
        parent_process();
    }

    printf("%s: %s exit\n", __func__, pid == 0 ? "child" : "parent");
    exit(0);
}


/* End of file */



